package demo4

import "fmt"

/*
	switch判断空接口中变量的类型
	1. type-switch 流程控制的语法或许是 Go语言中最古怪的语法。
		它可以被看作是类型断言的增强版。它和 switch-case 流程控制代码块有些相似。
	2. 一个 type-switch 流程控制代码块的语法如下所示：
		switch t := areaIntf.(type) {
			case *Square:
					fmt.Printf("Type Square %T with value %v\n", t, t)
			case *Circle:
					fmt.Printf("Type Circle %T with value %v\n", t, t)
			case nil:
					fmt.Printf("nil value: nothing to check?\n")
			default:
					fmt.Printf("Unexpected type %T\n", t)
			}
*/

/* demo1: 使用类型分支判断基本类型 */
func printType(v interface{}) {
	// v.(type) 就是类型分支的典型写法。通过这个写法，在 switch 的每个 case 中写的将是各种类型分支。
	switch v.(type) {
	case int:
		fmt.Println(v, "is int")
	case string:
		fmt.Println(v, "is string")
	case bool:
		fmt.Println(v, "is bool")
	}
}

/*
	demo2: 使用类型分支判断接口类型
	  1. 多个接口进行类型断言时，可以使用类型分支简化判断过程
*/

// Alipay 电子支付方式
type Alipay struct{}

// UseFaceID 实现 CanUseFaceID() 方法，表示刷脸支付
func (a *Alipay) UseFaceID() {
	fmt.Println("Alipay: 刷脸支付")
}

// Cash 现金支付
type Cash struct{}

// Stolen 实现 Stolen(), 表示会出现偷窃情况
func (c *Cash) Stolen() {
	fmt.Println("会被偷")
}

// CantainUseFaceID 刷脸特性的接口
type CantainUseFaceID interface {
	UseFaceID()
}

// ContainStolen 被偷特性的接口
type ContainStolen interface {
	Stolen()
}

// 打印支付方式具备的特点
func printPayType(payMenthod interface{}) {
	switch payMenthod.(type) {
	case CantainUseFaceID:
		fmt.Printf("%T can use faceId\n", payMenthod)
	case ContainStolen:
		fmt.Printf("%T maybe be stolen\n", payMenthod)
	}
}

// TestDemo412 类型分支（switch判断空接口中变量的类型）
func TestDemo412() {
	/* demo1 使用类型分支判断基本类型 */
	printType(1024)
	printType("pib")
	printType(true)

	/* demo2 使用类型分支判断接口类型 */
	// 电子支付
	printPayType(new(Alipay))
	// 现金支付
	printPayType(new(Cash))
}
